﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Win32;
using System.IO;
using System.Windows.Ink;

namespace InkCanvasControl
{
    /// <summary>
    /// CInkCanvas.xaml 的交互逻辑
    /// </summary>
    public partial class CInkCanvas : UserControl
    {
        Stroke str2;
        public CInkCanvas()
        {
            InitializeComponent();
            RigisterCommandToTarget();
            Touch.FrameReported += new TouchFrameEventHandler(Touch_FrameReported);
        }

        void Touch_FrameReported(object sender, TouchFrameEventArgs e)
        {
            if (this.inkCanv != null && inkCanv.EditingMode == InkCanvasEditingMode.Ink)
            {
                foreach (TouchPoint _touchPoint in e.GetTouchPoints(this.inkCanv))
                {
                    if (_touchPoint.Action == TouchAction.Down)
                    {
                        _touchPoint.TouchDevice.Capture(this.inkCanv);
                    }

                    else if (_touchPoint.Action == TouchAction.Move && e.GetPrimaryTouchPoint(this.inkCanv) != null)
                    {
                        if (_touchPoint.TouchDevice.Id != e.GetPrimaryTouchPoint(this.inkCanv).TouchDevice.Id)
                        {              
                            if (str2 != null && inkCanv.Strokes.Contains(str2))
                            {
                                str2.StylusPoints.Add(new StylusPoint(_touchPoint.Position.X, _touchPoint.Position.Y));
                            }
                            else
                            {
                                StylusPointCollection sc = new StylusPointCollection();
                                sc.Add(new StylusPoint(_touchPoint.Position.X, _touchPoint.Position.Y));
                                str2 = new Stroke(sc);
                                str2.DrawingAttributes = inkCanv.DefaultDrawingAttributes;
                                inkCanv.Strokes.Add(str2);
                            }
                        }
                    }

                    else if (_touchPoint.Action == TouchAction.Up)
                    {
                        if (_touchPoint.TouchDevice.Captured == this.inkCanv)
                        {
                            str2 = null;
                            this.inkCanv.ReleaseTouchCapture(_touchPoint.TouchDevice);
                        }
                    }
                }
            }
        }

        private void rad_Click(object sender, RoutedEventArgs e)
        {
            RadioButton rad = sender as RadioButton;
            this.inkCanv.EditingMode = (InkCanvasEditingMode)rad.Tag;
        }

        private void strokeThicknessSelector_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            Slider slider = sender as Slider;
            DrawingAttributes inkDA = new DrawingAttributes();
            inkDA.Width = inkDA.Height=slider.Value;
            inkDA.Color = inkCanv.DefaultDrawingAttributes.Color;
            inkDA.IsHighlighter = inkCanv.DefaultDrawingAttributes.IsHighlighter;
            inkCanv.DefaultDrawingAttributes = inkDA;   
        }
    }
    partial class CInkCanvas : UserControl
    {
        #region 命令
        /// <summary>
        /// 新建命令
        /// </summary>
        public static RoutedCommand NewCommand = new RoutedCommand();
        /// <summary>
        /// 打开命令
        /// </summary>
        public static RoutedCommand OpenCommand = new RoutedCommand();

        /// <summary>
        ///保存命令
        /// </summary>
        public static RoutedCommand SaveCommand = new RoutedCommand();

        /// <summary>
        ///剪切命令
        /// </summary>
        public static RoutedCommand CutCommand = new RoutedCommand();

        /// <summary>
        ///复制命令
        /// </summary>
        public static RoutedCommand CopyCommand = new RoutedCommand();

        /// <summary>
        /// 粘贴命令
        /// </summary>
        public static RoutedCommand PasteCommand = new RoutedCommand();

        /// <summary>
        /// 删除命令
        /// </summary>
        public static RoutedCommand DelCommand = new RoutedCommand();

        /// <summary>
        /// 全部选择命令
        /// </summary>
        public static RoutedCommand SelectAllCommand = new RoutedCommand();

        /// <summary>
        /// 设置颜色命令
        /// </summary>
        public static RoutedCommand SetColorCommand = new RoutedCommand();

        #endregion

        #region 注册命令
        void RigisterCommandToTarget()
        {
            CommandManager.RegisterClassCommandBinding(typeof(CInkCanvas), new CommandBinding(CInkCanvas.NewCommand, OnNewCommandExecuted, CanExecuteNewCommand));
            CommandManager.RegisterClassCommandBinding(typeof(CInkCanvas), new CommandBinding(CInkCanvas.OpenCommand, OnOpenCommandExecuted, CanExecuteOpenCommand));
            CommandManager.RegisterClassCommandBinding(typeof(CInkCanvas), new CommandBinding(CInkCanvas.SaveCommand, OnSaveCommandExecuted, CanExecuteSaveCommand));
            CommandManager.RegisterClassCommandBinding(typeof(CInkCanvas), new CommandBinding(CInkCanvas.CutCommand, OnCutCommandExecuted, CanExecuteCutCommand));
            CommandManager.RegisterClassCommandBinding(typeof(CInkCanvas), new CommandBinding(CInkCanvas.CopyCommand, OnCopyCommandExecuted, CanExecuteCopyCommand));
            CommandManager.RegisterClassCommandBinding(typeof(CInkCanvas), new CommandBinding(CInkCanvas.PasteCommand, OnPasteCommandExecuted, CanExecutePasteCommand));
            CommandManager.RegisterClassCommandBinding(typeof(CInkCanvas), new CommandBinding(CInkCanvas.DelCommand, OnDelCommandExecuted, CanExecuteDelCommand));
            CommandManager.RegisterClassCommandBinding(typeof(CInkCanvas), new CommandBinding(CInkCanvas.SelectAllCommand, OnSelectAllCommandExecuted, CanExecuteSelectAllCommand));
            CommandManager.RegisterClassCommandBinding(typeof(CInkCanvas), new CommandBinding(CInkCanvas.SetColorCommand, OnSetColorCommandExecuted, CanExecuteSetColorCommand));
            
        }
        #endregion

        #region 命令实现

        // 新建命令
        static void CanExecuteNewCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }
        static void OnNewCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            CInkCanvas root = sender as CInkCanvas;
            root.inkCanv.Strokes.Clear();
        }
        // 打开命令
        static void CanExecuteOpenCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }
        static void OnOpenCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            CInkCanvas root = sender as CInkCanvas;
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.CheckFileExists = true;
            dlg.Filter = "Ink格式 (*.isf)|*.isf|" +
                         "All files (*.*)|*.*";

            if ((bool)dlg.ShowDialog())
            {
                root.inkCanv.Strokes.Clear();

                try
                {
                    using (FileStream file = new FileStream(dlg.FileName,
                                                FileMode.Open, FileAccess.Read))
                    {
                        if (!dlg.FileName.ToLower().EndsWith(".isf"))
                        {
                            MessageBox.Show("打开的文件不是Ink的有效格式\r\n\r\n请重试.");
                        }
                        else
                        {
                            root.inkCanv.Strokes = new StrokeCollection(file);
                            file.Close();
                        }
                    }
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message);
                }
            }
        }

        // 保存命令
        static void CanExecuteSaveCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }
        static void OnSaveCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            CInkCanvas root = sender as CInkCanvas;
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.Filter = "Ink格式 (*.isf)|*.isf|" +
                         "Bitmap文件 (*.bmp)|*.bmp";

            if ((bool)dlg.ShowDialog())
            {
                try
                {
                    using (FileStream file = new FileStream(dlg.FileName,
                                            FileMode.Create, FileAccess.Write))
                    {
                        //Ink Serialized Format
                        if (dlg.FilterIndex == 1)
                        {
                            root.inkCanv.Strokes.Save(file);
                            file.Close();
                        }
                        //bitmap object
                        else
                        {
                            int marg = int.Parse(root.inkCanv.Margin.Left.ToString());
                            RenderTargetBitmap rtb = new RenderTargetBitmap((int)root.inkCanv.ActualWidth - marg,
                                            (int)root.inkCanv.ActualHeight - marg, 0, 0, PixelFormats.Default);
                            rtb.Render(root.inkCanv);
                            BmpBitmapEncoder encoder = new BmpBitmapEncoder();
                            encoder.Frames.Add(BitmapFrame.Create(rtb));
                            encoder.Save(file);
                            file.Close();
                        }
                    }
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message);
                }

            }
        }

        // 剪切命令
        static void CanExecuteCutCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            CInkCanvas root = sender as CInkCanvas;
            if (root.inkCanv.GetSelectedStrokes().Count > 0)
                e.CanExecute = true;
            else
            {
                e.CanExecute = false;
            }
        }
        static void OnCutCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            CInkCanvas root = sender as CInkCanvas;
            if (root.inkCanv.GetSelectedStrokes().Count > 0)
                root.inkCanv.CutSelection();
        }

        // 复制命令
        static void CanExecuteCopyCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            CInkCanvas root = sender as CInkCanvas;
            if (root.inkCanv.GetSelectedStrokes().Count > 0)
                e.CanExecute = true;
            else
            {
                e.CanExecute = false;
            }
        }
        static void OnCopyCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            CInkCanvas root = sender as CInkCanvas;
            if (root.inkCanv.GetSelectedStrokes().Count > 0)
                root.inkCanv.CopySelection();
        }

        // 粘贴命令
        static void CanExecutePasteCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            CInkCanvas root = sender as CInkCanvas;
            if (root.inkCanv.CanPaste())
                e.CanExecute = true;
            else
                e.CanExecute=false;
        }
        static void OnPasteCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            CInkCanvas root = sender as CInkCanvas;
            if (root.inkCanv.CanPaste())
                root.inkCanv.Paste();
        }

        // 删除命令
        static void CanExecuteDelCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            CInkCanvas root = sender as CInkCanvas;
            if (root.inkCanv.GetSelectedStrokes().Count > 0)
            {
                e.CanExecute = true;
            }
            else
            {
                e.CanExecute = false;
            }


        }
        static void OnDelCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            CInkCanvas root = sender as CInkCanvas;
            if (root.inkCanv.GetSelectedStrokes().Count > 0)
            {
                foreach (Stroke strk in root.inkCanv.GetSelectedStrokes())
                    root.inkCanv.Strokes.Remove(strk);
            }
        }

        //  选择全部命令
        static void CanExecuteSelectAllCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }
        static void OnSelectAllCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            CInkCanvas root = sender as CInkCanvas;
            root.inkCanv.Select(root.inkCanv.Strokes);
        }

        // 设置笔刷颜色命令
        static void CanExecuteSetColorCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }
        static void OnSetColorCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            CInkCanvas root = sender as CInkCanvas;
            System.Windows.Forms.ColorDialog cd = new System.Windows.Forms.ColorDialog();
            if (cd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                System.Drawing.Color c = cd.Color;
                Color mediac = new Color();
                mediac.A = c.A;
                mediac.R = c.R;
                mediac.G = c.G;
                mediac.B = c.B;

                root.inkCanv.DefaultDrawingAttributes.Color = mediac;
            }
        }

        #endregion
    }
}
